package com.gs.common.tool.utils;

import com.gs.common.tool.consts.FrameConst;
import com.gs.common.tool.pojo.ColumnInfo;
import lombok.extern.slf4j.Slf4j;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author guos
 * @date 2020/8/8 9:37
 **/
@Slf4j
public class PoJoUtil {


    private static final Pattern linePattern = Pattern.compile("_(\\w)");

    private static final Pattern humpPattern = Pattern.compile("[A-Z]");


    /**
     * 下划线转驼峰
     *
     * @param str str
     * @return String
     * @author guoshuai
     * @date 2021/12/25 17:50
     **/
    public static String lineToHump(String str) {
        str = str.toLowerCase();
        Matcher matcher = linePattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }


    /**
     * 驼峰转下划线,效率比上面高
     *
     * @param str 参数
     * @author guoshuai
     * @date 2022/4/16 9:43
     **/
    public static String humpToLine(String str) {
        Matcher matcher = humpPattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }


    /**
     * 首字母转大写
     * 先将字符串转换为char数组，然后一步到位，
     * 直接将数组首位字符ASCII码值减32，最后char数组转换为字符串
     */
    public static String firstToUpper(String str) {
        if (StringUtil.isEmpty(str)) {
            return null;
        }
        // 进行字母的ascii编码前移，效率要高于截取字符串进行转换的操作
        char[] cs = str.toCharArray();
        cs[0] -= 32;
        return String.valueOf(cs);
    }


    /**
     * 将字符串的首字母转小写
     * 需要转换的字符串
     */
    public static String firstToLower(String str) {
        // 同理
        char[] cs = str.toCharArray();
        cs[0] += 32;
        return String.valueOf(cs);
    }


    /**
     * 获取实体类名称
     *
     * @param pojoPrefix 实体类前缀
     * @param tableName    表名
     * @param pojoName     自定义类名
     * @date 2024/05/25 09:36
     **/
    public static String getEntityName(String pojoPrefix, String tableName, String pojoName) {
        if (StringUtil.isNotEmpty(pojoName)) {
            return pojoName;
        }
        String simpleName = StringUtil.isNotEmpty(pojoPrefix) ? pojoPrefix + "_" + tableName : tableName;
        String name = PoJoUtil.lineToHump(simpleName);
        return name.substring(0, 1).toUpperCase() + name.substring(1);
    }

    /**
     * 获取类包路径
     *
     * @param classFullName 类全名
     * @date 2024/07/15 15:10
     **/
    public static String getPackName(String classFullName) {
        return classFullName.substring(0, classFullName.lastIndexOf('.'));
    }


    /**
     * 获取类短名
     *
     * @param classFullName 类全名
     * @date 2024/07/15 15:10
     **/
    public static String getShortName(String classFullName) {
        return classFullName.substring(classFullName.lastIndexOf('.') + 1);
    }

    /**
     * 输出属性信息
     * @param frame    框架类型
     * @param columnInfo    列信息
     * @date 2024/11/18 09:50
     **/
    public static String outputFields(String frame, ColumnInfo columnInfo) {
        if (StringUtil.isEmpty(columnInfo)) {
            return "";
        }
        boolean isTk = FrameConst.TK.equals(frame);
        String columnName = columnInfo.getColumnName();
        String fieldName = lineToHump(columnName);
        String columnType = columnInfo.getColumnType();
        String comment = columnInfo.getColumnComment();
        //是否主键
        boolean isPk = columnInfo.isPK();
        //tk框架
        if (isTk) {
            if (isPk) {
                return String.format("\n\n\t/**\n\t* 主键\n\t*/\n\t@Id\n\tprivate %s %s;", DbTypeToJavaTypeUtil.dbTypeToJavaTypeName(columnType), fieldName);
            }
            return String.format("\n\n\t/**\n\t* %s\n\t*/\n\t@Column(name = \"%s\")\n\tprivate %s %s;", comment, columnName, DbTypeToJavaTypeUtil.dbTypeToJavaTypeName(columnType), fieldName);
        }
        if (isPk) {
            return String.format("\n\n\t/**\n\t* 主键\n\t*/\n\t@JsonSerialize(using = ToStringSerializer.class)\n\t@TableId(value = \"%s\",type = IdType.ASSIGN_ID)\n\tprivate %s %s;", columnName, DbTypeToJavaTypeUtil.dbTypeToJavaType(columnType), fieldName);
        }
        return String.format("\n\n\t/**\n\t* %s\n\t*/\n\t@TableField(\"%s\")\n\tprivate %s %s;", comment, columnName, DbTypeToJavaTypeUtil.dbTypeToJavaTypeName(columnType), fieldName);
    }
}
